const axios = require('axios')
const fs = require('fs-extra')
const path = require('path')
const StreamZip = require('node-stream-zip')
const clusterJson = require('../cluster.json')
const { token, host, port, protocol, uefile } = clusterJson
const { get, post } = require('../utils/request')
// 文件同步状态
// const syncFileStatus = new Map()
/**
 * @description: 下载ue文件
 * @param {*} sourceUrl
 * @param {*} destPath
 * @param {*} onProgress
 * @return {*}
 */
const downloadFile = async (sourceUrl, destPath, onProgress) => {
  const response = await axios({
    method: 'get',
    url: `${protocol}://${host}:${port}${sourceUrl}`,
    headers: {
      Authorization: 'Bearer ' + token
    },
    responseType: 'stream',
    // 注意：可以通过 'maxContentLength' 和 'maxBodyLength' 设置大小限制
    timeout: 0 // 设置超时时间，例如2分钟
  })

  const writer = fs.createWriteStream(destPath)

  let totalLength = response.headers['content-length']
  let downloadedLength = 0

  response.data.on('data', chunk => {
    downloadedLength += chunk.length
    if (onProgress) {
      onProgress(downloadedLength, totalLength)
    }
  })

  response.data.pipe(writer)

  return new Promise((resolve, reject) => {
    writer.on('finish', resolve)

    // 注意：如果使用管道，错误应该从目标流中捕获
    writer.on('error', reject)

    response.data.on('error', reject) // 捕获响应数据流错误
  })
}
const deleteUefile = async data => {
  // 删除ue源文件
  await fs.remove(data.originalPath)
  // 删除ue工程文件
  await fs.remove(data.path)
  // 删除cluster.json中数据
  // 指定配置文件路径
  const clusterPath = path.resolve(__dirname, '../cluster.json') // 根据您的实际配置文件位置来更改路径
  // 读取 JSON 配置文件内容
  const clusterJson = await fs.readJson(clusterPath)
  // 修改配置文件
  clusterJson.uefile = clusterJson.uefile.filter(
    item => item._id !== data.fileId
  )
  // 写回 JSON 配置文件
  await fs.writeJson(clusterPath, clusterJson, { spaces: 2 })
}

/**
 * @description: 同步文件
 * @return {*}
 */
/**
 * @description:对比本地和远程文件差异，返回需要下载的文件列表
 * @return {Array} needDownload
 */
const checkLocalFile = async () => {
  const needDownload = []
  const needDelete = []
  // 拉取ue工程文件数据，并找到需要更新的文件
  const getUefiles = await get('/upload/getUefiles')
  let remoteData = []
  if (getUefiles.status) {
    remoteData = [...getUefiles.data]
  }
  // 指定配置文件路径
  const clusterPath = path.resolve(__dirname, '../cluster.json') // 根据您的实际配置文件位置来更改路径
  // 读取 JSON 配置文件内容
  const clusterJson = await fs.readJson(clusterPath)
  console.log('remoteData == ', remoteData)
  console.log('uefile == ', uefile)
  //  整理需要下载内容
  remoteData.forEach(item => {
    const target = clusterJson.uefile.find(file => file._id == item._id)
    if (!target) {
      needDownload.push(item)
    }
  })
  //   整理需要删除内容
  clusterJson.uefile.forEach(item => {
    const target = remoteData.find(file => file._id == item._id)
    if (!target) {
      needDelete.push(item)
    }
  })
  return { needDownload, needDelete }
}

const unzipUe = async (filePath, fileName, taskId) => {
  const outputPath = path.resolve(__dirname, `../ueproject/${fileName}`)
  await fs.ensureDir(outputPath) // 确保输出目录存在
  // 创建一个 StreamZip 实例来解压文件
  const zip = new StreamZip.async({ file: filePath })
  // 解压缩到 outputDir 目录
  try {
    const entries = await zip.entries()
    // const totalCount = Object.keys(entries).length
    // let extractedCount = 0

    for (const entry of Object.values(entries)) {
      // 完整路径
      const fullPath = path.join(outputPath, entry.name)

      if (entry.isDirectory) {
        // 如果是目录则创建之
        await fs.ensureDir(fullPath)
        // extractedCount++
        continue
      }

      // 确保文件的父目录存在
      await fs.ensureDir(path.dirname(fullPath))

      // 解压缩单个文件
      await zip.extract(entry.name, fullPath)
      //   extractedCount++
      // 更新解压进度到 unzipUeStatus
      //   const percentage = Math.ceil((extractedCount / totalCount) * 100)
      //   syncFileStatus.set(taskId, {
      //     type: 'unzip',
      //     status: false,
      //     percentage
      //   })
    }
    // syncFileStatus.set(taskId, {
    //   type: 'unzip',
    //   status: true
    // })
    //   解压部署完成更新主控机文件数据库
    await post('/uefile/updatesyncFile', {
      id: taskId,
      path: outputPath,
      deployStatus: true
    })
    console.log(fileName, ' 解压完成')
  } catch (err) {
    console.log('解压出错', err)
  } finally {
    await zip.close()
  }
}
/**
 * @description:下载所需文件
 * @return {*}
 */

const syncFile = async clusterId => {
  const { needDownload, needDelete } = await checkLocalFile()
  console.log('需要更新的文件列表', needDownload)
  console.log('需要删除的文件列表', needDelete)
  //   当需要删除的文件列表长度大于0，则进行删除工作
  if (needDelete.length > 0) {
    // 获取数据库中跟集群相关的uefile数据
    const syncFiles = await post('/uefile/getsyncFile', {
      pageSize: -1,
      pageNo: 1,
      clusterId: clusterId
    })
    const deleteIds = []
    needDelete.forEach(async item => {
      const target = syncFiles.data.find(file => {
        return file.fileId == item._id
      })
      if (target) {
        deleteIds.push(target._id)
        await deleteUefile(target)
      }
    })
    // 发送数据删除主控机记录
    await post('/uefile/deletesyncFile', { ids: deleteIds })
  }
  // 当需要更新的列表长度大于0，则进行下载工作
  if (needDownload.length) {
    await fs.ensureDir(path.resolve(__dirname, '../uefile')) // 确保输出目录存在
    needDownload.forEach(async d => {
      const ueporjectName = d.originalFilename.split('.')[0] || 'ueproject'
      // 在主控机ue文件数据库注册数据
      const uefileRes = await post('/uefile/addsyncFile', {
        clusterId: clusterId,
        clusterHost: process.env.HOST,
        fileId: d._id,
        name: ueporjectName
      })
      if (uefileRes.status) {
        console.log(ueporjectName, ' 下载开始')
        const url = `/uefile/download/${d.originalFilename}`
        const destPath = path.resolve(
          __dirname,
          '../uefile',
          d.originalFilename
        )
        downloadFile(
          url,
          destPath
          //     , (downloadedLength, totalLength) => {
          //   const percentage = Math.ceil((downloadedLength / totalLength) * 100)
          //   syncFileStatus.set(uefileRes.data._id, {
          //     type: 'download',
          //     status: false,
          //     percentage
          //   })
          // }
        ).then(async () => {
          //   syncFileStatus.set(uefileRes.data._id, {
          //     type: 'download',
          //     status: true
          //   })
          //   下载完成更新主控机文件数据库
          await post('/uefile/updatesyncFile', {
            id: uefileRes.data._id,
            originalPath: destPath,
            downloadStatus: true
          })
          console.log(ueporjectName, ' 解压开始')
          await unzipUe(destPath, ueporjectName, uefileRes.data._id)
          //   存储已经完成内容,用于下次同步文件对比
          // 指定配置文件路径
          const clusterPath = path.resolve(__dirname, '../cluster.json') // 根据您的实际配置文件位置来更改路径
          // 读取 JSON 配置文件内容
          const clusterJson = await fs.readJson(clusterPath)
          // 修改配置文件
          clusterJson.uefile.push(d)
          // 写回 JSON 配置文件
          await fs.writeJson(clusterPath, clusterJson, { spaces: 2 })
        })
      }
    })
  }
}
module.exports = {
  downloadFile,
  syncFile
  //   syncFileStatus
}
